package cn.fintecher.pangolin.service.business.service;

import cn.fintecher.pangolin.common.enums.*;
import cn.fintecher.pangolin.common.exception.BadRequestException;
import cn.fintecher.pangolin.common.model.UserModel;
import cn.fintecher.pangolin.common.utils.Constants;
import cn.fintecher.pangolin.common.utils.ZWDateUtil;
import cn.fintecher.pangolin.entity.elastic.BaseCase;
import cn.fintecher.pangolin.entity.elastic.HistoryCases;
import cn.fintecher.pangolin.entity.elastic.OtherRecord;
import cn.fintecher.pangolin.entity.mysql.CaseInfo;
import cn.fintecher.pangolin.service.business.model.request.AddWorkOrderRequest;
import cn.fintecher.pangolin.service.business.model.request.CaseToNormalRequest;
import cn.fintecher.pangolin.service.business.model.request.DeleteReturnCasesRequest;
import cn.fintecher.pangolin.service.business.repository.elasticsearch.BaseCaseRespository;
import cn.fintecher.pangolin.service.business.repository.elasticsearch.HistoryCasesRespository;
import cn.fintecher.pangolin.service.business.repository.elasticsearch.OtherRecordElastic;
import cn.fintecher.pangolin.service.business.repository.jparepository.CaseInfoRepository;
import cn.fintecher.pangolin.service.business.repository.jparepository.DepartmentRepository;
import cn.fintecher.pangolin.service.business.repository.jparepository.UserRepository;
import com.google.common.collect.Lists;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

@Service
public class HistoryCasesService {

    @Autowired
    private HistoryCasesRespository historyCasesRespository;

    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;

    @Autowired
    private CaseInfoRepository caseInfoRepository;

    @Autowired
    private BaseCaseRespository baseCaseRespository;

    @Autowired
    private OtherRecordElastic otherRecordElastic;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private DepartmentRepository departmentRepository;

    /**
     * @Author wangxiangdong
     * @Description 退案案件池删除案件
     * @Date 2019/9/10 10:36
     **/
    public void deleteCases(DeleteReturnCasesRequest deleteReturnCasesRequest) {
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        List<HistoryCases> personalList = new ArrayList<>();
        if (Objects.nonNull(deleteReturnCasesRequest.getPersonalIds())) {
            queryBuilder.must(termsQuery("id.keyword", deleteReturnCasesRequest.getPersonalIds()));
        }
        if (Objects.nonNull(deleteReturnCasesRequest.getBatchNumber())) {
            queryBuilder.must(termsQuery("batchNumber.keyword", deleteReturnCasesRequest.getBatchNumber()));
        }
        Iterator<HistoryCases> iterator = historyCasesRespository.search(queryBuilder).iterator();
        while (iterator.hasNext()) {
            HistoryCases historyCases = iterator.next();
            historyCases.setHistoryCaseStatus(HistoryCaseStatus.DELETE_POOL);
            historyCases.setDeleteCaseDate(ZWDateUtil.getNowDateTime());
            personalList.add(historyCases);
        }
        historyCasesRespository.saveAll(personalList);
    }

    /**
     * @Author wangxiangdong
     * @Description 获取退案案件的批次号
     * @Date 2019/9/10 10:59
     *
     * @param userModel*/
    public List<String> getReturnCasesBatchNumber(UserModel userModel) {
        List<String> batchNumberList = new ArrayList<>();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        if(Objects.equals(userModel.getIsCheck(),BaseSelect.YES)){
            boolQueryBuilder.must(QueryBuilders.termsQuery("principalId.keyword",userModel.getPrincipalIds()));
        }
        boolQueryBuilder.must(QueryBuilders.matchPhraseQuery("historyCaseStatus.keyword", HistoryCaseStatus.RETIRE_POOL.name()));
        TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms("batchNumber").field("batchNumber.keyword");
        SearchQuery searchQuery = new NativeSearchQueryBuilder().withIndices(Constants.HISTORY_CASES)
                .withTypes(Constants.HISTORY_CASES)
                .withQuery(boolQueryBuilder)
                .addAggregation(termsAggregationBuilder).build();
        Aggregations aggregations = elasticsearchTemplate.query(searchQuery, SearchResponse::getAggregations);
        Map<String, Aggregation> map = aggregations.asMap();
        if (map.get("batchNumber") instanceof StringTerms) {
            StringTerms stringTerms = (StringTerms) map.get("batchNumber");
            for (StringTerms.Bucket bucket : stringTerms.getBuckets()) {
                batchNumberList.add(bucket.getKeyAsString());
            }
        }
        return batchNumberList;
    }

    /**
     * @Author wangxiangdong
     * @Description 案件永久删除
     * @Date 2019/9/10 16:11
     **/
    public void deleteCasesPermanent(DeleteReturnCasesRequest deleteReturnCasesRequest) {
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        if (Objects.nonNull(deleteReturnCasesRequest.getPersonalIds())) {
            queryBuilder.must(termsQuery("id.keyword", deleteReturnCasesRequest.getPersonalIds()));
        }
        if (Objects.nonNull(deleteReturnCasesRequest.getBatchNumber())) {
            queryBuilder.must(termsQuery("batchNumber.keyword", deleteReturnCasesRequest.getBatchNumber()));
        }
        Iterable<HistoryCases> personalIterable = historyCasesRespository.search(queryBuilder);
        historyCasesRespository.deleteAll(personalIterable);
    }

    /**
     * @Author wangxiangdong
     * @Description 获取删除案件的批次号
     * @Date 2019/9/10 16:32
     *
     * @param userModel*/
    public List<String> getDeleteCasesBatchNumber(UserModel userModel) {
        List<String> batchNumberList = new ArrayList<>();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        if(Objects.equals(userModel.getIsCheck(),BaseSelect.YES)){
            boolQueryBuilder.must(QueryBuilders.termsQuery("principalId.keyword",userModel.getPrincipalIds()));
        }
        boolQueryBuilder.must(QueryBuilders.matchPhraseQuery("historyCaseStatus.keyword", HistoryCaseStatus.DELETE_POOL.name()));
        TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms("batchNumber").field("batchNumber.keyword");
        SearchQuery searchQuery = new NativeSearchQueryBuilder().withIndices(Constants.HISTORY_CASES)
                .withTypes(Constants.HISTORY_CASES)
                .withQuery(boolQueryBuilder)
                .addAggregation(termsAggregationBuilder).build();
        Aggregations aggregations = elasticsearchTemplate.query(searchQuery, SearchResponse::getAggregations);
        Map<String, Aggregation> map = aggregations.asMap();
        if (map.get("batchNumber") instanceof StringTerms) {
            StringTerms stringTerms = (StringTerms) map.get("batchNumber");
            for (StringTerms.Bucket bucket : stringTerms.getBuckets()) {
                batchNumberList.add(bucket.getKeyAsString());
            }
        }
        return batchNumberList;
    }

    /**
     * @Author wangxiangdong
     * @Description 退案恢复
     * @Date 2019/9/11 9:34
     **/
    @Transactional
    public void recoverCaseToNormal(CaseToNormalRequest caseToNormalRequest, String operator) {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.termsQuery("id.keyword", caseToNormalRequest.getIds()));
        List<HistoryCases> historyCases = Lists.newArrayList(historyCasesRespository.search(boolQueryBuilder).iterator());
        List<CaseInfo> caseInfoList = new ArrayList<>();
        List<BaseCase> baseCaseList = new ArrayList<>();
        for (HistoryCases historyCase : historyCases) {
            boolean user = userRepository.existsById(historyCase.getCurrentCollector().getId());
            if (!user && Objects.nonNull(historyCase.getCurrentCollector())) {
                historyCase.setDepartment(historyCase.getCurrentCollector().getDepartment());
                historyCase.setCurrentCollector(null);
                boolean dept = departmentRepository.existsById(historyCase.getDepartment().getId());
                if (!dept && Objects.nonNull(historyCase.getDepartment())) {
                    historyCase.setDepartment(departmentRepository.getOne(historyCase.getDepartment().getParentId()));
                }
            }
            BaseCase baseCase = new BaseCase();
            BeanUtils.copyProperties(historyCase, baseCase);
            baseCase.setOperateTime(ZWDateUtil.getNowDateTime());
            baseCaseList.add(baseCase);
            if (Objects.equals(historyCase.getIsDistribute(), BaseSelect.YES)) {
                CaseInfo caseInfo = new CaseInfo();
                BeanUtils.copyProperties(historyCase, caseInfo);
                caseInfo.setAddress(historyCase.getHomeAddr());
                caseInfo.setCurrentCollector(historyCase.getCurrentCollector());
                //假如催收员不为空  则说明案件为在催状态
                if (Objects.nonNull(historyCase.getCurrentCollector())) {
                    caseInfo.setCaseDataStatus(CaseDataStatus.IN_POOL);
                }
                caseInfo.setDepartment(historyCase.getDepartment());
                caseInfo.setPublicCaseFlag(PublicCaseFlag.NO_PUBLIC_CASE);
                caseInfo.setOperator(operator);
                caseInfo.setEndCaseDate(caseToNormalRequest.getEndCaseDate());
                caseInfo.setOperatorTime(ZWDateUtil.getNowDateTime());
                caseInfoList.add(caseInfo);
            }
        }
        if (caseInfoList.size() > 0) {
            caseInfoRepository.saveAll(caseInfoList);
        }
        baseCaseRespository.saveAll(baseCaseList);
        historyCasesRespository.deleteAll(historyCases);
    }

    public void addHistoryCaseWorkerOrder(AddWorkOrderRequest request, UserModel userModel) {
        HistoryCases historyCases = historyCasesRespository.findById(request.getCaseId()).orElseThrow(() -> new BadRequestException(null, "caseInfo", "case.is.null"));
        OtherRecord otherRecord = new OtherRecord();
        otherRecord.setCaseId(historyCases.getId()); //案件ID
        otherRecord.setCaseNumber(historyCases.getCaseNumber()); //案件编号
        otherRecord.setFindTime(request.getDate());
        otherRecord.setId(UUID.randomUUID().toString().replaceAll("-", "")); //主键ID
        otherRecord.setRecord(request.getContent());
        otherRecord.setCertificateNo(historyCases.getCertificateNo());
        otherRecord.setOtherFollowType(OtherFollowType.WORKORDER);
        otherRecord.setPrincipalId(historyCases.getPrincipalId()); //委托方ID
        otherRecord.setPrincipalName(historyCases.getPrincipalName()); //委托方名称
        otherRecord.process(userModel.getId(), userModel.getRealName(), ZWDateUtil.getNowDateTime());
        otherRecordElastic.save(otherRecord);
    }
}
